■ RS232C シリアル通信
![]()
■ ASCII 文字列の送受信(PC-PIC間) <PIC18F4550>
RS232Cによる送受信を理解するには、デリゲート、マルチスレッド、文字コード等に関する若干の知識が必要となります。
以下に例を紹介します。PICと通信を行った例でPIC側はPIC側回路&ソフトを参照願います
<試作品の仕様>
・パソコン側は.NETのC++とし、RS232Cシリアル通信を用いPIC18F4550と文字列の送受信をおこなう。
・PIC側のコンボボックスにあらかじめ下記の文字をセットしておきボタンをクリックすると選択されていた文字列を送信する。
送信される文字の最後尾には’¥r’付加する。
PIC側ではこれらの文字列を受信したら所定の文字列をPC側に返信する。
Oda → Nobunaga
Toyotomi → Hideyoshi
Tokugawa → Ieyasu
Tanaka → Pardon?
・ PIC側では受信文字、送信文字を液晶に表示する。
・ PC側でも受信文字をテキストボックスに表示する。
| <プログラム 例1> Form1.h |
||||
|
namespace VC232CASCII
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Text;//エンコードクラスを使用する場合要追加
public ref class Form1 : public System::Windows::Forms::Form
{
//受信スレッドから文字を取り込みテキストボックス textboxにデータを
//書き込むデリゲート関数を宣言する。
delegate void mySetTextCallback(String^ text);
public:
Form1(void)
{
InitializeComponent();
comboBox1->Items->Clear();
comboBox1->Items->Insert(0,"Oda");
comboBox1->Items->Insert(1,"Toyotomi");
comboBox1->Items->Insert(2,"Tokugawa");
comboBox1->Items->Insert(3,"Tanaka");
comboBox1->SelectedIndex = 0;
serialPort1->PortName = "COM4"; //COM4 ポート使用
serialPort1->BaudRate = 9600; //9600bps
serialPort1->Parity = System::IO::Ports::Parity::None; //パリティなし
serialPort1->DataBits = 8; //データ長 8ビット
serialPort1->StopBits = System::IO::Ports::StopBits::One; //ストップビット 1
serialPort1->NewLine = "\r\n";//ReadLine(),WriteLine()が末尾と判断する値の設定
//\r\n:defalut Windows \n: Unix
serialPort1->Open();
serialPort1->DtrEnable = true; //DTR(Data Terminal Ready) データ端末レディ
serialPort1->RtsEnable = true; //RTS(Request To Send) 送信要求
serialPort1->ReadTimeout = 500; //500mse 読み込みタイムアウト時間
serialPort1->WriteTimeout = 500; //500msec書き込みタイムアウト時間
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
String^ strSend = comboBox1->Text;
if (!strSend->EndsWith("\r")) strSend += "\r"; //改行が無かったら \rを追加する
serialPort1->Write(strSend);
}
private: System::
Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
SetText(serialPort1->ReadExisting());
}
void SetText(String^ text)
{
if (this->textBox1->InvokeRequired) //invoke メソッドを呼び出す必要があるなら
//別スレッドからの呼び出しであるなら
{
mySetTextCallback^ d = gcnew mySetTextCallback(this,&VC232CASCII::Form1::SetText);
//デリゲート関数へのインスタンスを生成し、SetText()関数へ割り当てる。
this->Invoke(d,gcnew String(text)); //デリゲートの非同期実行機能により、メインスレッドの
//textBox1テキストボックスへ、受信時刻とは時間差をもって書き込む
}
else
{
textBox1->Clear();
textBox1->AppendText(text);
}
}
private: System::
Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e)
{
serialPort1->Close();
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::ComboBox^ comboBox1;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->button1 = (gcnew System::Windows::Forms::Button());
this->comboBox1 = (gcnew System::Windows::Forms::ComboBox());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(185, 52);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(83, 30);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// comboBox1
//
this->comboBox1->FormattingEnabled = true;
this->comboBox1->Location = System::Drawing::Point(39, 58);
this->comboBox1->Name = L"comboBox1";
this->comboBox1->Size = System::Drawing::Size(92, 20);
this->comboBox1->TabIndex = 1;
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(39, 146);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(112, 19);
this->textBox1->TabIndex = 2;
//
// serialPort1
//
this->serialPort1->DataReceived +=
gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 263);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->comboBox1);
this->Controls->Add(this->button1);
this->Name = L"Form1";
this->Text = L"Form1";
this->FormClosed +=
gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Form1_FormClosed);
this->ResumeLayout(false);
this->PerformLayout();
}
};
}
|
||||
<プログラム 例2> Form1.h |
||||
<プログラム例>
namespace VC232CASCII {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Text;//エンコードクラスを使用する場合要追加
public ref class Form1 : public System::Windows::Forms::Form
{
//受信スレッドから文字を取り込みテキストボックス textboxにデータを
//書き込むデリゲート関数を宣言する。
delegate void ReceiveDelegate(String^ text);
private :
void SetText(String^ str)
{
textBox1->Text = str;
}
public:
Form1(void)
{
InitializeComponent();
comboBox1->Items->Clear();
comboBox1->Items->Insert(0,"Oda");
comboBox1->Items->Insert(1,"Toyotomi");
comboBox1->Items->Insert(2,"Tokugawa");
comboBox1->Items->Insert(3,"Takeda");
comboBox1->SelectedIndex = 0;
serialPort1->PortName = "COM4"; //COM4 ポート使用
serialPort1->BaudRate = 9600; //9600bps
serialPort1->Parity = System::IO::Ports::Parity::None; //パリティなし
serialPort1->DataBits = 8; //データ長 8ビット
serialPort1->StopBits = System::IO::Ports::StopBits::One; //ストップビット 1
serialPort1->NewLine = "\r\n";//ReadLine(),WriteLine()が末尾と判断する値の設定
//\r\n:defalut Windows \n: Unix
serialPort1->Open();
serialPort1->DtrEnable = true; //DTR(Data Terminal Ready) データ端末レディ
serialPort1->RtsEnable = true; //RTS(Request To Send) 送信要求
serialPort1->ReadTimeout = 500; //500mse 読み込みタイムアウト時間
serialPort1->WriteTimeout = 500; //500msec書き込みタイムアウト時間
}
private: System::
Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
array <Byte>^ bytesArry; //ダイナミック配列の宣言
Encoding^ encSjis = Encoding::GetEncoding("shift-jis"); //シフトJISのエンコードクラスを宣言
String^ strSend = comboBox1->Text; //
if (!strSend->EndsWith("\r")) strSend += "\r"; //改行が無かったら \rを追加する
bytesArry = encSjis->GetBytes( strSend ); //'送信文字をunicode→Shift-jisに変換してをByte配列に格納
serialPort1->Write(bytesArry,0,bytesArry->Length);//送信
}
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
Encoding^ encSjis = Encoding::GetEncoding("shift-jis"); //シフトJISのエンコードクラスを宣言
Encoding^ encUni = Encoding::GetEncoding("unicode"); //ユニコード(UCS-16)のエンコードクラスを宣言
array<Byte>^byteRead = gcnew array<Byte>(serialPort1->BytesToRead); //バイト単位の配列を生成
serialPort1->Read(byteRead, 0, serialPort1->BytesToRead);//バイト配列を受信
array<Byte>^byteUni = Encoding::Convert(encSjis, encUni, byteRead); //shift-jis からunicodeに変換する
String^ strUni = encUni->GetString(byteUni); //配列をunicodeの文字列に変換
ReceiveDelegate^ receiveDelegate = gcnew ReceiveDelegate(this,&VC232CASCII::Form1::SetText); //デリゲートのインスタンス生成
this->Invoke(receiveDelegate, strUni); //セカンドスレッドからメインスレッドへinvoke経由で書き込み
}
private: System::Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e)
{
serialPort1->Close();
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::ComboBox^ comboBox1;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::Windows::Forms::Label^ label1;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->button1 = (gcnew System::Windows::Forms::Button());
this->comboBox1 = (gcnew System::Windows::Forms::ComboBox());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));
this->label1 = (gcnew System::Windows::Forms::Label());
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(185, 52);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(83, 30);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// comboBox1
//
this->comboBox1->FormattingEnabled = true;
this->comboBox1->Location = System::Drawing::Point(39, 58);
this->comboBox1->Name = L"comboBox1";
this->comboBox1->Size = System::Drawing::Size(92, 20);
this->comboBox1->TabIndex = 1;
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(39, 146);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(112, 19);
this->textBox1->TabIndex = 2;
//
// serialPort1
//
this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived);
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(231, 121);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(37, 12);
this->label1->TabIndex = 3;
this->label1->Text = L"type 2";
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 263);
this->Controls->Add(this->label1);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->comboBox1);
this->Controls->Add(this->button1);
this->Name = L"Form1";
this->Text = L"Form1";
this->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Form1_FormClosed);
this->ResumeLayout(false);
this->PerformLayout();
}
};
}
|
||||
| 動作結果 | ||||
![]() |
![]() |
![]() |
![]() |
|
ASCII 文字列の送受信(PC-PIC間) <PIC24F>
VC++を使い英数字文字列の送受信をおこなう。
<試作品の仕様> → PIC側ソフト
・パソコン側は.NETのVC++とし、RS232Cシリアル通信を用いPIC24Fと英数字文字列の送受信をおこなう。
・PC側のコンボボックスにあらかじめ下記の文字をセットしておきボタンをクリックすると選択されていた文字列を送信する。
送信される文字の最後尾には’¥r’付加する。
PIC側ではこれらの文字列を受信したら以下の文字列をPC側に返信する。
Sakamoto → Ryouma
Saigou → Takamori
Katsura → Kogorou
その他 → Pardon?
・ PIC側では受信文字、送信文字を液晶に表示する。
・ PC側でも受信文字をテキストボックス 及びリストに表示する。
| <プログラム 例> Form1.h |
|
#pragma once
namespace My1003RS23224FJText {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Text;//エンコードクラスを使用する場合要追加
public ref class Form1 : public System::Windows::Forms::Form
{
//受信スレッドから文字を取り込みテキストボックス textboxにデータを
//書き込むデリゲート関数を宣言する。
delegate void mySetTextCallback(String^ text);
public:
Form1(void)
{
InitializeComponent();
comboBox1->Items->Clear(); //コンボボックス値クリア
comboBox1->Items->Insert(0,"Sakamoto"); //Item[0]設定
comboBox1->Items->Insert(1,"Saigou"); //Item[1]設定
comboBox1->Items->Insert(2,"Katsura"); //Item[2]設定
comboBox1->Items->Insert(3,"Hellow !!"); //Item[3]設定
comboBox1->SelectedIndex = 0;
listBox1->Items->Clear(); //リストボックス値クリア
serialPort1->PortName = "COM4"; //COM4 ポート使用
serialPort1->BaudRate = 9600; //9600bps
serialPort1->Parity = System::IO::Ports::Parity::None; //パリティなし
serialPort1->DataBits = 8; //データ長 8ビット
serialPort1->StopBits = System::IO::Ports::StopBits::One; //ストップビット 1
serialPort1->NewLine = "\r\n";//ReadLine(),WriteLine()が末尾と判断する値の設定
//\r\n:defalut Windows \n: Unix
serialPort1->Open();
serialPort1->DtrEnable = true; //DTR(Data Terminal Ready) データ端末レディ
serialPort1->RtsEnable = true; //RTS(Request To Send) 送信要求
serialPort1->ReadTimeout = 500; //500mse 読み込みタイムアウト時間
serialPort1->WriteTimeout = 500; //500msec書き込みタイムアウト時間
}
private: System::
Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
String^ strSend = comboBox1->Text;
if (!strSend->EndsWith("\r")) strSend += "\r"; //改行が無かったら \rを追加する
serialPort1->Write(strSend);
}
private: System::
Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
SetText(serialPort1->ReadExisting());
}
void SetText(String^ text)
{
if (this->textBox1->InvokeRequired) //invoke メソッドを呼び出す必要があるなら
//別スレッドからの呼び出しであるなら
{
mySetTextCallback^ d = gcnew mySetTextCallback(this,&My1003RS23224FJText::Form1::SetText);
//デリゲート関数へのインスタンスを生成し、SetText()関数へ割り当てる。
this->Invoke(d,gcnew String(text)); //デリゲートの非同期実行機能により、メインスレッドの
//textBox1テキストボックスへ、受信時刻とは時間差をもって書き込む
}
else
{
textBox1->Clear();
textBox1->AppendText(text);
listBox1->Items->Add(text);
}
}
private: System::
Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e)
{
serialPort1->Close();
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::ComboBox^ comboBox1;
protected:
protected:
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Label^ label2;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::Windows::Forms::ListBox^ listBox1;
private: System::Windows::Forms::Label^ label3;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->comboBox1 = (gcnew System::Windows::Forms::ComboBox());
this->label1 = (gcnew System::Windows::Forms::Label());
this->label2 = (gcnew System::Windows::Forms::Label());
this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));
this->button1 = (gcnew System::Windows::Forms::Button());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->listBox1 = (gcnew System::Windows::Forms::ListBox());
this->label3 = (gcnew System::Windows::Forms::Label());
this->SuspendLayout();
//
// comboBox1
//
this->comboBox1->Font = (gcnew System::Drawing::Font(L"MS ゴシック", 11.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->comboBox1->FormattingEnabled = true;
this->comboBox1->Location = System::Drawing::Point(12, 43);
this->comboBox1->Name = L"comboBox1";
this->comboBox1->Size = System::Drawing::Size(121, 23);
this->comboBox1->TabIndex = 0;
//
// label1
//
this->label1->AutoSize = true;
this->label1->Font = (gcnew System::Drawing::Font(L"MS UI Gothic", 14.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->label1->Location = System::Drawing::Point(19, 21);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(97, 19);
this->label1->TabIndex = 2;
this->label1->Text = L"送信データ";
//
// label2
//
this->label2->AutoSize = true;
this->label2->Font = (gcnew System::Drawing::Font(L"MS UI Gothic", 14.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->label2->Location = System::Drawing::Point(294, 21);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(97, 19);
this->label2->TabIndex = 3;
this->label2->Text = L"受信データ";
//
// serialPort1
//
this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived);
//
// button1
//
this->button1->Location = System::Drawing::Point(162, 43);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 4;
this->button1->Text = L"送信";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// textBox1
//
this->textBox1->Font = (gcnew System::Drawing::Font(L"MS ゴシック", 11.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->textBox1->Location = System::Drawing::Point(280, 47);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(120, 22);
this->textBox1->TabIndex = 5;
//
// listBox1
//
this->listBox1->Font = (gcnew System::Drawing::Font(L"MS ゴシック", 11.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->listBox1->FormattingEnabled = true;
this->listBox1->ItemHeight = 15;
this->listBox1->Location = System::Drawing::Point(280, 104);
this->listBox1->Name = L"listBox1";
this->listBox1->Size = System::Drawing::Size(120, 94);
this->listBox1->TabIndex = 6;
//
// label3
//
this->label3->AutoSize = true;
this->label3->Font = (gcnew System::Drawing::Font(L"MS UI Gothic", 14.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->label3->Location = System::Drawing::Point(294, 82);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(89, 19);
this->label3->TabIndex = 7;
this->label3->Text = L"受信履歴";
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(457, 210);
this->Controls->Add(this->label3);
this->Controls->Add(this->listBox1);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->button1);
this->Controls->Add(this->label2);
this->Controls->Add(this->label1);
this->Controls->Add(this->comboBox1);
this->Name = L"Form1";
this->Text = L"Form1";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
}
};
}
|
<実行結果>
| PC側画面 | PIC側液晶画面 1行目: 受信文字 2行目: 返信文字 |
|
| @ | ![]() 上記ダイアログは以下の順番でコンボボックスの送信データを 選択して、送信した時のものです。 @ Sakamoto A Saigou B katusra C Hellow !! |
![]() |
| A | ![]() |
|
| B | ![]() |
|
| C | ![]() |
■ 漢字文字列の送受信(PC−PIC間)
PCとPIC(PIC18F4550)間でのシフトJISによる漢字の送受信の例を紹介します。
<試作品の仕様> → PIC側ソフト、ハード
・パソコン側は.NETのC++とし、RS232Cシリアル通信を用いPIC18F4550と文字列の送受信をおこなう。
・PC側のコンボボックスにあらかじめ下記の文字をセットしておく。送信ボタンをクリックして選択されていた文字列を送信する。
送信される文字の最後尾には’¥r’付加する。
PIC側ではこれらの文字列を受信したら、以下に定めた文字列をPC側に返信する。
織田(織:0x9044 田:0x9363) → 0x904D(信) 0x92B7(長)
豊臣(豊:0x964C 臣:0x9062) → 0x8F47(秀) 0x8B67(吉)
徳川(徳:0x93BF 川:0x90EC) → 0x89C6(家) 0x8D4E(康)
田中 → Pardon?
・ PIC側では受信文字を16進数表示で受信文字 及び送信文字を液晶に表示する。
・ PC側では、受信文字を漢字でテキストボックスに表示する。
| <プログラム 例> Form1.h |
|
namespace VC232CASCII {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Text;//エンコードクラスを使用する場合要追加
public ref class Form1 : public System::Windows::Forms::Form
{
//受信スレッドから文字を取り込みテキストボックス textboxにデータを
//書き込むデリゲート関数を宣言する。
delegate void ReceiveDelegate(String^ text);
private :
void SetText(String^ str)
{
textBox1->Text = str;
}
public:
Form1(void)
{
InitializeComponent();
comboBox1->Items->Clear();
comboBox1->Items->Insert(0,"織田");
comboBox1->Items->Insert(1,"豊臣");
comboBox1->Items->Insert(2,"徳川");
comboBox1->Items->Insert(3,"田中");
comboBox1->SelectedIndex = 0;
serialPort1->PortName = "COM4"; //COM4 ポート使用
serialPort1->BaudRate = 9600; //9600bps
serialPort1->Parity = System::IO::Ports::Parity::None; //パリティなし
serialPort1->DataBits = 8; //データ長 8ビット
serialPort1->StopBits = System::IO::Ports::StopBits::One; //ストップビット 1
serialPort1->NewLine = "\r\n";//ReadLine(),WriteLine()が末尾と判断する値の設定
//\r\n:defalut Windows \n: Unix
serialPort1->Open();
serialPort1->DtrEnable = true; //DTR(Data Terminal Ready) データ端末レディ
serialPort1->RtsEnable = true; //RTS(Request To Send) 送信要求
serialPort1->ReadTimeout = 500; //500mse 読み込みタイムアウト時間
serialPort1->WriteTimeout = 500; //500msec書き込みタイムアウト時間
}
private: System::
Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
array <Byte>^ bytesArry; //ダイナミック配列の宣言
Encoding^ encSjis = Encoding::GetEncoding("shift-jis"); //シフトJISのエンコードクラスを宣言
String^ strSend = comboBox1->Text; //
if (!strSend->EndsWith("\r")) strSend += "\r"; //改行が無かったら \rを追加する
bytesArry = encSjis->GetBytes( strSend ); //'送信文字をunicode→Shift-jisに変換してをByte配列に格納
serialPort1->Write(bytesArry,0,bytesArry->Length);//送信
}
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
Encoding^ encSjis = Encoding::GetEncoding("shift-jis"); //シフトJISのエンコードクラスを宣言
Encoding^ encUni = Encoding::GetEncoding("unicode"); //ユニコード(UCS-16)のエンコードクラスを宣言
array<Byte>^byteRead = gcnew array<Byte>(serialPort1->BytesToRead); //バイト単位の配列を生成
serialPort1->Read(byteRead, 0, serialPort1->BytesToRead);//バイト配列を受信
array<Byte>^byteUni = Encoding::Convert(encSjis, encUni, byteRead); //shift-jis からunicodeに変換する
String^ strUni = encUni->GetString(byteUni); //配列をunicodeの文字列に変換
ReceiveDelegate^ receiveDelegate = gcnew ReceiveDelegate(this,&VC232CASCII::Form1::SetText); //デリゲートのインスタンス生成
this->Invoke(receiveDelegate, strUni); //セカンドスレッドからメインスレッドへinvoke経由で書き込み
}
private: System::Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e)
{
serialPort1->Close();
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::ComboBox^ comboBox1;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::Windows::Forms::Label^ label1;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->button1 = (gcnew System::Windows::Forms::Button());
this->comboBox1 = (gcnew System::Windows::Forms::ComboBox());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));
this->label1 = (gcnew System::Windows::Forms::Label());
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(185, 52);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(83, 30);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// comboBox1
//
this->comboBox1->FormattingEnabled = true;
this->comboBox1->Location = System::Drawing::Point(39, 58);
this->comboBox1->Name = L"comboBox1";
this->comboBox1->Size = System::Drawing::Size(92, 20);
this->comboBox1->TabIndex = 1;
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(39, 146);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(112, 19);
this->textBox1->TabIndex = 2;
//
// serialPort1
//
this->serialPort1->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &Form1::serialPort1_DataReceived);
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(231, 121);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(37, 12);
this->label1->TabIndex = 3;
this->label1->Text = L"type 2";
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 263);
this->Controls->Add(this->label1);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->comboBox1);
this->Controls->Add(this->button1);
this->Name = L"Form1";
this->Text = L"Form1";
this->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Form1_FormClosed);
this->ResumeLayout(false);
this->PerformLayout();
}
};
}
|
<実行結果>
| 送受信文字 (シフトJIS) |
PC側 | PIC側 (上段:受信データ 下段:送信データ) |
||
| 織田信長 織:0x9044 田:0x9363 信:0x904D 長:0x92B7 |
![]() |
![]() |
||
| 豊臣秀吉 豊:0x964C 臣:0x9062 秀:0x8F47 吉:0x8B67 |
![]() |
![]() |
||
| 徳川家康 徳:0x93BF 川:0x90EC 家:0x89C6 康:0x8D4E |
![]() |
![]() |
(注) 液晶表示で1、2バイト目と3、4バイト目の間に1文字分の空白がありますが、これは液晶表示する際漢字(2バイト)データをわかりやすく
するために表示制御で挿入した空白です。実際の送受信においては、4バイトデータの中間に空白データ(0x00など)はありません
■ RS232C送受信データ波形観測( .NET − PIC間通信)
PCとPIC間で実際に送受信されるRS232Cの信号をビットレベルで観測した結果を紹介します。PCからのデータ送信プログラムを紹介します。
回路図等ハードについては ( →RS232C送受信波形観測回路図等 )を参照願います
<試作品の仕様>
・ PCからPICに文字データをおくり、PCのTX 及びPICのRXの波形を観測する
・ 送信データは下記とする
@ A
A B
B C
C AA
・ データの形式は以下のとする
@ スタートビット : 1 ビット固定
A データビット : 8 ビット固定
B ストップビット : 1 ビット固定
C パリティ : なし
| <プログラム例> Form1.h |
|
#pragma once
namespace My1003PS232HakeiKansoku {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Text;//エンコードクラスを使用する場合要追加
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
comboBox1->Items->Clear(); //コンボボックス値クリア
comboBox1->Items->Insert(0,"A"); //Item[0]設定
comboBox1->Items->Insert(1,"B"); //Item[1]設定
comboBox1->Items->Insert(2,"C"); //Item[2]設定
comboBox1->Items->Insert(3,"AA"); //Item[3]設定
comboBox1->SelectedIndex = 0;
serialPort1->PortName = "COM4"; //COM4 ポート使用
serialPort1->BaudRate = 9600; //9600bps
serialPort1->Parity = System::IO::Ports::Parity::None; //パリティなし
serialPort1->DataBits = 8; //データ長 8ビット
serialPort1->StopBits = System::IO::Ports::StopBits::One; //ストップビット 1
serialPort1->NewLine = "\r\n";//ReadLine(),WriteLine()が末尾と判断する値の設定
//\r\n:defalut Windows \n: Unix
serialPort1->Open();
serialPort1->DtrEnable = true; //DTR(Data Terminal Ready) データ端末レディ
serialPort1->RtsEnable = true; //RTS(Request To Send) 送信要求
serialPort1->ReadTimeout = 500; //500mse 読み込みタイムアウト時間
serialPort1->WriteTimeout = 500; //500msec書き込みタイムアウト時間
}
protected:
private: System::
Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
String^ strSend = comboBox1->Text;
serialPort1->Write(strSend);
}
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::ComboBox^ comboBox1;
protected:
private: System::Windows::Forms::Button^ button1;
private: System::IO::Ports::SerialPort^ serialPort1;
private: System::ComponentModel::IContainer^ components;
private:
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->comboBox1 = (gcnew System::Windows::Forms::ComboBox());
this->button1 = (gcnew System::Windows::Forms::Button());
this->serialPort1 = (gcnew System::IO::Ports::SerialPort(this->components));
this->SuspendLayout();
//
// comboBox1
//
this->comboBox1->Font = (gcnew System::Drawing::Font(L"MS UI Gothic", 12, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->comboBox1->FormattingEnabled = true;
this->comboBox1->Location = System::Drawing::Point(23, 31);
this->comboBox1->Name = L"comboBox1";
this->comboBox1->Size = System::Drawing::Size(121, 24);
this->comboBox1->TabIndex = 0;
//
// button1
//
this->button1->Font = (gcnew System::Drawing::Font(L"MS UI Gothic", 12, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(128)));
this->button1->Location = System::Drawing::Point(179, 29);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 1;
this->button1->Text = L"送信";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 135);
this->Controls->Add(this->button1);
this->Controls->Add(this->comboBox1);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
#pragma endregion
};
}
|
<結果>
<PC側送信画面>
PCの左記画面から A、B、C、AA の各文字 及び文字列をRS232Cで送信した画面です。

<測定結果>
測定結果を以下に示します
| 受信文字 (16進数表示) (2進数表示) |
受信パルス実測波形(パリティなし) 上側:PICのRX端子波形 下側:PCのTX端子波形 |
| A (0x41) (0b01000001) |
![]() |
| B (0x42) (0b01000010) |
![]() |
| C (0x43) (0b01000011) |
![]() |
| AA (0x41 + 0x41) (0b01000001+ 0b01000001) |
![]() |